/**
 * 实现声音的播放
 * 创建者：Carburn Ashroom
 * 2023.1.7
 */

#include "sound.h"

namespace Sound {

    bool Bgm::bgm_is_playing {false};
    bool Bgm::is_pause {false};
    Information Bgm::inform {Information::none};
    int Effect::effect_num {0};

    void Bgm::play() const
    {
        if (bgm_is_playing)
            throw Multy_bgm_error{};
        bgm_is_playing = true;
        inform = Information::none;
        is_pause = false;
        std::thread play_thread {thread_play_bgm,get_path(),get_alias()};
        play_thread.detach();
    }

    void Bgm::init_sound()
    {
        set_alias(bgm_alias);
    }

    void Bgm::send_message(Information message)
    {
        inform = message;
        sleep_for(2*bgm_wait);
    }

    void Bgm::thread_play_bgm(string file_name, string alias)
    {
        ostringstream open_cmd;
        open_cmd << R"(open ")" << file_name << R"(" alias ")" << alias << '\"';
        string open_str {open_cmd.str()};
        mciSendStringA(open_str.c_str(), nullptr, 0, nullptr);
        string play_str {string{R"(play ")"}+alias+R"(" repeat)"};
        mciSendStringA(play_str.c_str(), nullptr, 0, nullptr);
        for ( ; ; ) {
            switch (inform) {
            case Information::pause:
                if (!is_pause) {
                    is_pause = true;
                    mciSendStringA((string{R"(pause ")"}+alias+'\"').c_str(), nullptr, 0, nullptr);
                }
                break;
            case Information::resume:
                if (is_pause) {
                    is_pause = false;
                    mciSendStringA((string{R"(resume ")"}+alias+'\"').c_str(), nullptr, 0, nullptr);
                }
                break;
            case Information::stop:
                bgm_is_playing = false;
                mciSendStringA((string{R"(stop ")"}+alias+'\"').c_str(), nullptr, 0, nullptr);
                return;
            default:
                break;
            }
            inform = Information::none;
            sleep_for(bgm_wait);
        }
    }

    void Effect::play() const
    {
        std::thread sound {thread_play_effect,get_path(),get_alias()};
        sound.detach();
    }

    void Effect::init_sound()
    {
        int index {effect_num++};
        ostringstream c_str;
        c_str << "sound_effect" << index;
        set_alias(c_str.str());
    }

    void Effect::thread_play_effect(std::string file_name, std::string alias)
    {
        ostringstream open_cmd;
        open_cmd << R"(open ")" << file_name << R"(" alias )" << alias;
        mciSendStringA(open_cmd.str().c_str(), nullptr, 0, nullptr);
        string play_cmd {string{"play "}+alias+" wait"};
        mciSendStringA(play_cmd.c_str(), nullptr, 0, nullptr);
    }

}
